package com.ctshk.rpc.tour.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ctshk.common.enums.*;
import com.ctshk.rpc.tour.dto.cache.Trip;
import com.ctshk.rpc.tour.entity.*;
import com.ctshk.rpc.tour.mapper.*;
import com.ctshk.rpc.tour.req.es.TripCacheUpdateReq;
import com.ctshk.rpc.tour.service.ISeriesTripAppService;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.service.support.BaseService;
import com.ctshk.common.utils.Assist;
import com.ctshk.common.utils.BConst;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.insurance.dto.InsuranceSellDTO;
import com.ctshk.rpc.insurance.service.IInsuranceProductService;
import com.ctshk.rpc.order.tour.code.CostSharingType;
import com.ctshk.rpc.system.service.IMainDataTourGroupAreaService;
import com.ctshk.rpc.system.service.IMainDataTourGroupCodeService;
import com.ctshk.rpc.system.service.ISysPermissionService;
import com.ctshk.rpc.tour.dto.SeriesTripDTO;
import com.ctshk.rpc.tour.dto.SeriesTripTouristTypeDTO;
import com.ctshk.rpc.tour.dto.TripBasicInformationDTO;
import com.ctshk.rpc.tour.dto.TripFileDTO;
import com.ctshk.rpc.tour.dto.TripInsuranceSellDTO;
import com.ctshk.rpc.tour.dto.TripVisaListDTO;
import com.ctshk.rpc.tour.req.Passenger;
import com.ctshk.rpc.tour.req.SeriesTripInfoChangeRuleReq;
import com.ctshk.rpc.tour.req.SeriesTripItineraryDayReq;
import com.ctshk.rpc.tour.req.SeriesTripReq;
import com.ctshk.rpc.tour.req.SeriesTripScheduleItineraryDayReq;
import com.ctshk.rpc.tour.req.SeriesTripTeamRuleReq;
import com.ctshk.rpc.tour.req.SimpleJourneyReq;
import com.ctshk.rpc.tour.req.TripListQueryReq;
import com.ctshk.rpc.tour.req.TripSupplementReq;
import com.ctshk.rpc.tour.req.trip.AddTripFileReq;
import com.ctshk.rpc.tour.req.trip.FileReq;
import com.ctshk.rpc.tour.req.trip.TripApprovalReq;
import com.ctshk.rpc.tour.req.trip.TripInsuranceReq;
import com.ctshk.rpc.tour.req.trip.TripVisaReq;
import com.ctshk.rpc.tour.req.trip.UpdateStatusReq;
import com.ctshk.rpc.tour.req.trip.UpdateTripScheduleStatusReq;
import com.ctshk.rpc.tour.service.ISeriesTripService;
import com.ctshk.rpc.visa.dto.visa.VisaListDTO;
import com.ctshk.rpc.visa.req.visa.VisaListReq;
import com.ctshk.rpc.visa.service.IVisaService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.dto.ApprovalStartDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;

import ma.glasnost.orika.MapperFactory;

/**
 * <p>
 * 系列团行程 服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-01-12
 */
@DubboService
public class SeriesTripServiceImpl extends ServiceImpl<SeriesTripMapper, SeriesTrip> implements ISeriesTripService, BaseService {

    /**
     * 团队规则服务
     */
    @Autowired
    private SeriesTripTeamRuleMapper seriesTripTeamRuleMapper;

    /**
     * 数据转换
     */
    @Autowired
    private MapperFactory mapperFactory;

    /**
     * 行程信息服务
     */
    @Autowired
    private SeriesTripScheduleItineraryDayMapper seriesTripScheduleItineraryDayMapper;

    /**
     * 系列团--团期服务
     */
    @Autowired
    private SeriesTripScheduleServiceImpl seriesTripScheduleService;

    /**
     * 系列团--团期服务
     */
    @Autowired
    private SeriesTripScheduleMapper seriesTripScheduleMapper;


    /**
     * 行程文件
     */
    @Autowired
    private SeriesTripFilesMapper seriesTripFilesMapper;

    /**
     * 行程--旅客类型
     */
    @Autowired
    private SeriesTripTouristTypeMapper seriesTripTouristTypeMapper;

    /**
     * 签证
     */
    @Autowired
    private SeriesTripVisaMapper visaMapper;
    /**
     * 保险
     */
    @Autowired
    private SeriesTripInsuranceMapper insuranceMapper;

    /**
     * 签证服务
     */
    @DubboReference
    private IVisaService iVisaService;

    /**
     * 保险服务
     */
    @DubboReference
    private IInsuranceProductService iInsuranceProductService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 数据权限接口
     */
    @DubboReference
    private ISysPermissionService sysPermissionService;

    /**
     * 旅客规则服务
     */
    @Autowired
    private SeriesTripInfoChangeRuleMapper seriesTripInfoChangeRuleMapper;

    /**
     * 工作流服务
     */
    @DubboReference
    private ISysApprovalService sysApprovalService;

    /**
     * 系统旅游分组目的服务
     */
    @DubboReference
    private IMainDataTourGroupAreaService mainDataTourGroupAreaService;

    /**
     * 系统旅游分组码服务
     */
    @DubboReference
    private IMainDataTourGroupCodeService mainDataTourGroupCodeService;

    @Autowired
    SeriesTripMapper seriesTripMapper;

    @Autowired
    SeriesTripDefaultCostMapper seriesTripDefaultCostMapper;

    @Autowired
    SeriesTripDefaultCostGroupMapper seriesTripDefaultCostGroupMapper;

    @Autowired
    SeriesTripElasticSearchMapper seriesTripElasticSearchMapper;

    @Autowired
    SeriesTripCustomSalePriceMapper seriesTripCustomSalePriceMapper;

    @Autowired
    private ISeriesTripAppService iSeriesTripAppService;
    @Autowired
    SeriesTripCustomCostMapper seriesTripCustomCostMapper;

    @Override
    public TripBasicInformationDTO basicInformation(Long id) {
        //行程基本信息
        SeriesTrip seriesTrip = baseMapper.selectById(id);
        SeriesTripReq seriesTripReq = new SeriesTripReq();
        BeanUtils.copyProperties(seriesTrip, seriesTripReq);

        //行程团队信息
        SeriesTripTeamRule seriesTripTeamRule = seriesTripTeamRuleMapper.selectOne(new QueryWrapper<SeriesTripTeamRule>().lambda().eq(SeriesTripTeamRule::getTripId, id));
        SeriesTripTeamRuleReq seriesTripTeamRuleReq = new SeriesTripTeamRuleReq();
        BeanUtils.copyProperties(seriesTripTeamRule, seriesTripTeamRuleReq);
        //负责人
        seriesTripTeamRuleReq.setChargePersonId(seriesTrip.getChargePersonId());
        seriesTripTeamRuleReq.setChargePersonName(seriesTrip.getChargePersonName());
        seriesTripTeamRuleReq.setChargePersonNumber(seriesTrip.getChargePersonNumber());
//        UserDTO userDto = (UserDTO) redisTemplate.opsForValue().get(RedisConstants.ACCOUNT_QUERY_KEY + seriesTrip.getChargePersonId());
//        if (userDto!=null&&StringUtils.isNotBlank(userDto.getDept())){
//            seriesTripTeamRuleReq.setChargePersonDepartment(userDto.getDept());
//        }

        //操作人
        seriesTripTeamRuleReq.setOpId(seriesTrip.getOpId());
        seriesTripTeamRuleReq.setOpName(seriesTrip.getOpName());
        seriesTripTeamRuleReq.setOpNumber(seriesTrip.getOpNumber());
//        UserDTO opDto = (UserDTO) redisTemplate.opsForValue().get(RedisConstants.ACCOUNT_QUERY_KEY + seriesTrip.getOpId());
//        if (opDto!=null&&StringUtils.isNotBlank(opDto.getDept())){
//            seriesTripTeamRuleReq.setOpDepartment(opDto.getDept());
//        }

        List<SeriesTripTouristType> seriesTripTouristTypeList = seriesTripTouristTypeMapper.selectList(new QueryWrapper<SeriesTripTouristType>().lambda().eq(SeriesTripTouristType::getTripId, id).orderByDesc(SeriesTripTouristType::getSort));
        List<Passenger> passengerList = new ArrayList<>();
        for (SeriesTripTouristType seriesTripTouristType : seriesTripTouristTypeList) {
            Passenger passenger = new Passenger();
            passenger.setSort(seriesTripTouristType.getSort());
            passenger.setAgeBegin(seriesTripTouristType.getAgeBegin());
            passenger.setAgeEnd(seriesTripTouristType.getAgeEnd());
            passenger.setId(seriesTripTouristType.getId());
            passenger.setMainDataId(seriesTripTouristType.getMainDataId());
            passenger.setName(seriesTripTouristType.getName());
            passenger.setIsOccupyBed(seriesTripTouristType.getIsOccupyBed());
            passengerList.add(passenger);
        }
        seriesTripTeamRuleReq.setPassenger(passengerList);

        List<SeriesTripInfoChangeRule> seriesTripInfoChangeRules = seriesTripInfoChangeRuleMapper.selectList(new QueryWrapper<SeriesTripInfoChangeRule>().lambda().eq(SeriesTripInfoChangeRule::getTripId, id));
        List<SeriesTripInfoChangeRuleReq> changeRuleList = EntityUtil.copyList(seriesTripInfoChangeRules, SeriesTripInfoChangeRuleReq.class);
        seriesTripTeamRuleReq.setChangeRuleList(changeRuleList);

        //签证信息
        List<SeriesTripVisa> visaList = visaMapper.selectList(new QueryWrapper<SeriesTripVisa>().lambda().eq(SeriesTripVisa::getTripId, id));
        List<TripVisaListDTO> tripVisaListDTOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(visaList)) {
            List<TripVisaReq> tripVisaList = EntityUtil.copyList(visaList, TripVisaReq.class);
            seriesTripReq.setTripVisaList(tripVisaList);
            VisaListReq visaListReq = new VisaListReq();
            List<String> ids = new ArrayList<>();
            for (SeriesTripVisa seriesTripVisa : visaList) {
                ids.add(seriesTripVisa.getVisaId().toString());
            }
            visaListReq.setIds(ids);
            try {
                Result<List<VisaListDTO>> result = iVisaService.visaList(visaListReq);

                if (result.isSuccess()) {
                    List<VisaListDTO> visaListDTOList = result.getData();
                    tripVisaListDTOList = EntityUtil.copyList(visaListDTOList, TripVisaListDTO.class);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        //保险信息
        List<SeriesTripInsurance> seriesTripInsuranceList = insuranceMapper.selectList(new QueryWrapper<SeriesTripInsurance>().lambda().eq(SeriesTripInsurance::getTripId, id));
        List<TripInsuranceSellDTO> tripInsuranceSellDTOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(seriesTripInsuranceList)) {
            List<TripInsuranceReq> insuranceList = EntityUtil.copyList(seriesTripInsuranceList, TripInsuranceReq.class);
            seriesTripReq.setInsuranceList(insuranceList);
            List<Long> insuranceIdList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(seriesTripInsuranceList)) {
                for (SeriesTripInsurance seriesTripInsurance : seriesTripInsuranceList) {
                    insuranceIdList.add(seriesTripInsurance.getInsuranceId());
                }
                List<InsuranceSellDTO> insuranceSellDTOList = iInsuranceProductService.queryAll(insuranceIdList);
                tripInsuranceSellDTOList = EntityUtil.copyList(insuranceSellDTOList, TripInsuranceSellDTO.class);
            }
        }

        TripBasicInformationDTO tripBasicInformationDTO = new TripBasicInformationDTO();
        tripBasicInformationDTO.setId(id);
        tripBasicInformationDTO.setSeriesTripReq(seriesTripReq);
        tripBasicInformationDTO.setSeriesTripTeamRuleReq(seriesTripTeamRuleReq);
        tripBasicInformationDTO.setTripVisaListDTOList(tripVisaListDTOList);
        tripBasicInformationDTO.setTripInsuranceSellDTOList(tripInsuranceSellDTOList);
        return tripBasicInformationDTO;
    }

    @Override
    public void supplement(TripSupplementReq tripSupplementReq) {
        //修改行程--补充资料
        SeriesTrip seriesTrip = mapperFactory.getMapperFacade().map(tripSupplementReq, SeriesTrip.class);
        baseMapper.updateById(seriesTrip);

        // 更新缓存
        CompletableFuture.runAsync(() -> {
            iSeriesTripAppService.updateTripCache(new TripCacheUpdateReq().setIds(Arrays.asList(seriesTrip.getId())));
        });
    }

    @Override
    public TripSupplementReq tripSupplement(Long id) {
        SeriesTrip seriesTrip = baseMapper.selectById(id);
        TripSupplementReq tripSupplementReq = new TripSupplementReq();
        BeanUtils.copyProperties(seriesTrip, tripSupplementReq);
        return tripSupplementReq;
    }

    @Override
    public SeriesTripScheduleItineraryDayReq tripItineraryInformation(Long id) {
        SeriesTrip seriesTrip = baseMapper.selectById(id);
        //行程类型
        SeriesTripScheduleItineraryDayReq seriesTripScheduleItineraryDayReq = new SeriesTripScheduleItineraryDayReq();
        Integer itineraryType = seriesTrip.getItineraryType();
        seriesTripScheduleItineraryDayReq.setItineraryType(seriesTrip.getItineraryType());
        seriesTripScheduleItineraryDayReq.setId(seriesTrip.getId());
        if (null != itineraryType && itineraryType == 2) {
            SimpleJourneyReq simpleJourneyReq = new SimpleJourneyReq();
            simpleJourneyReq.setSimpleItinerary(seriesTrip.getSimpleItinerary());
            seriesTripScheduleItineraryDayReq.setSimpleJourneyReq(simpleJourneyReq);
        }

        if (null != itineraryType && itineraryType == 1) {
            List<SeriesTripScheduleItineraryDay> list = seriesTripScheduleItineraryDayMapper.selectList(new QueryWrapper<SeriesTripScheduleItineraryDay>().lambda().eq(SeriesTripScheduleItineraryDay::getTripId, id));
            List<SeriesTripItineraryDayReq> dayReqList = EntityUtil.copyList(list, SeriesTripItineraryDayReq.class);
            seriesTripScheduleItineraryDayReq.setList(dayReqList);
        }
        return seriesTripScheduleItineraryDayReq;
    }

    @Override
    public PageResponse<SeriesTripDTO> tripList(TripListQueryReq tripListQueryReq, TokenUser tokenUser) {
        return queryTripListHandle(tripListQueryReq, tokenUser.getId(), true);
    }

    /**
     * CMS查询行程列表
     *
     * @param tripListQueryReq
     * @return
     */
    @Override
    public PageResponse<SeriesTripDTO> queryCmsTripList(TripListQueryReq tripListQueryReq) {
        return queryTripListHandle(tripListQueryReq, null, false);
    }

    /**
     * 查询行程列表逻辑处理
     *
     * @param tripListQueryReq
     * @param userId
     * @param isPermission     是否权限过滤
     */
    private PageResponse<SeriesTripDTO> queryTripListHandle(TripListQueryReq tripListQueryReq, Long userId, boolean isPermission) {
        if (tripListQueryReq.getBusinessType() == null) {
            tripListQueryReq.setBusinessType(1);
        }
        QueryWrapper<SeriesTrip> queryWrapper = new QueryWrapper<SeriesTrip>();

        //权限过滤
        if (isPermission) {
            Result<List<Long>> permission = sysPermissionService.queryPermission(tripListQueryReq.getMenuId(), userId);

            if (!permission.isSuccess() || CollectionUtils.isEmpty(permission.getData())) {
                SystemError error = SystemError.USER_1001;
                throw new BusinessException(error);
            }

            List<Long> userList = permission.getData();
            if (CollectionUtils.isEmpty(userList)) {
                return new PageResponse<>(new ArrayList<>(), true, true, 0, 1, 10);
            }

            queryWrapper.lambda().and(wrapper -> wrapper.in(SeriesTrip::getChargePersonId, userList).or().in(SeriesTrip::getOpId, userList));
        }
        IPage<SeriesTrip> page = new Page<SeriesTrip>(tripListQueryReq.getPageNo(), tripListQueryReq.getPageSize());
        queryWrapper.lambda().eq(SeriesTrip::getIsDeleted, 0);
        queryWrapper.lambda().eq(SeriesTrip::getBusinessType, tripListQueryReq.getBusinessType());
        //      queryWrapper.lambda().in(SeriesTrip::getChargePersonId, userList);
        if (StringUtils.isNotBlank(tripListQueryReq.getTitle())) {
            queryWrapper.lambda().and(wrapper -> wrapper.like(SeriesTrip::getTitle, tripListQueryReq.getTitle()).or().like(SeriesTrip::getTripCode, tripListQueryReq.getTitle()));
        }
        if (StringUtils.isNotBlank(tripListQueryReq.getTitleEq())) {
            queryWrapper.lambda().and(wrapper -> wrapper.like(SeriesTrip::getTitle, tripListQueryReq.getTitleEq()));
        }
        if (StringUtils.isNotBlank(tripListQueryReq.getTripCode())) {
            queryWrapper.lambda().and(wrapper -> wrapper.like(SeriesTrip::getTripCode, tripListQueryReq.getTripCode()));
        }
        if (StringUtils.isNotBlank(tripListQueryReq.getTourGroupCode())) {
            queryWrapper.lambda().eq(SeriesTrip::getTourGroupCode, tripListQueryReq.getTourGroupCode());
        }
        if (tripListQueryReq.getDeparturePlaceId() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getDeparturePlaceId, tripListQueryReq.getDeparturePlaceId());
        }
        if (tripListQueryReq.getDestinationId() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getDestinationId, tripListQueryReq.getDestinationId());
        }
        if (tripListQueryReq.getStatus() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getStatus, tripListQueryReq.getStatus());
        }
        if (tripListQueryReq.getTourTypeId() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getTourTypeId, tripListQueryReq.getTourTypeId());
        }

        if (tripListQueryReq.getChargePersonId() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getChargePersonId, tripListQueryReq.getChargePersonId());
        }

        if (tripListQueryReq.getOpId() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getOpId, tripListQueryReq.getOpId());
        }

        if (tripListQueryReq.getTravelDays() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getTravelDays, tripListQueryReq.getTravelDays());
        }

        if (tripListQueryReq.getGroupNatureId() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getGroupNatureId, tripListQueryReq.getGroupNatureId());
        }

        if (tripListQueryReq.getGroupNatureId() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getGroupNatureId, tripListQueryReq.getGroupNatureId());
        }

        if (tripListQueryReq.getGroupTypeId() != null) {
            queryWrapper.lambda().eq(SeriesTrip::getGroupTypeId, tripListQueryReq.getGroupTypeId());
        }

        if (tripListQueryReq.getTourThemeJson() != null) {
            queryWrapper.lambda().like(SeriesTrip::getTourThemeJson, tripListQueryReq.getTourThemeJson());
        }
        queryWrapper.lambda().orderByDesc(SeriesTrip::getGmtCreate);

        IPage<SeriesTrip> iPage = baseMapper.selectPage(page, queryWrapper);
        List<SeriesTrip> seriesTripList = iPage.getRecords();
        List<SeriesTripDTO> seriesTripDTOList = EntityUtil.copyList(seriesTripList, SeriesTripDTO.class);
        //      for (SeriesTripDTO seriesTripDTO : seriesTripDTOList) {
        //          UserDTO userDto = (UserDTO) redisTemplate.opsForValue().get(RedisConstants.ACCOUNT_QUERY_KEY + seriesTripDTO.getChargePersonId());
        //          if (userDto!=null&&StringUtils.isNotBlank(userDto.getDept())){
        //              seriesTripDTO.setChargePersonDepartment(userDto.getDept());
        //          }
        //          UserDTO opDto = (UserDTO) redisTemplate.opsForValue().get(RedisConstants.ACCOUNT_QUERY_KEY + seriesTripDTO.getOpId());
        //          if (opDto!=null&&StringUtils.isNotBlank(opDto.getDept())){
        //              seriesTripDTO.setOpDepartment(opDto.getDept());
        //          }
        //      }

        return new PageResponse<>(seriesTripDTOList, iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    //TODO
    @Override
    public void updateTripStatus(UpdateStatusReq updateStatusReq, TokenUser tokenUser) {
        SeriesTrip seriesTrip = new SeriesTrip();
        seriesTrip.setId(updateStatusReq.getId());
        Integer status = updateStatusReq.getStatus();
        if (status.equals(TripStatusConstants.INVALID.getCode())) {
            seriesTrip.setStatus(TripStatusConstants.INVALID.getCode());
        }
        if (status.equals(TripStatusConstants.EFFECTIVE.getCode())) {
            SeriesTrip dbEntity = seriesTripMapper.assertExistById(updateStatusReq.getId());
            BigDecimal groupCustomerPrice = null;
            //自定义成本分摊
            if (CostSharingType.CUSTOM.getCode().equals(dbEntity.getCostSharingType())) {
                List<SeriesTripCustomSalePrice> seriesTripCustomSalePriceList = seriesTripCustomSalePriceMapper.selectListByKey("trip_id", dbEntity.getId());
                if (Assist.isNotEmpty(seriesTripCustomSalePriceList)) {
                    for (SeriesTripCustomSalePrice item : seriesTripCustomSalePriceList) {
                        if (item.getGroupCustomerPrice() != null) {
                            groupCustomerPrice = item.getGroupCustomerPrice();
                            break;
                        }
                    }
                }
            } else {  //默认成本分摊
                SeriesTripDefaultCost seriesTripDefaultCost = seriesTripDefaultCostMapper.selectOneByKey("trip_id", dbEntity.getId());
                groupCustomerPrice = Assist.ifNotNullFn(seriesTripDefaultCost, SeriesTripDefaultCost::getGroupCustomerPrice);
            }

            if (groupCustomerPrice == null) {
                throwException(SystemError.TOUR_30011);
            }

            // todo 进行行程审批

//            tokenUser.setId(1344284712813568L);//目前固定用户和类型测试
            long approvalTypeId = SysApprovalType.TRAVEl_OUTTRA.getCode();
            Result<ApprovalStartDTO> result = sysApprovalService.start(SystemBusinessType.OUTBOUND_TRAVEL.getCode(), approvalTypeId, seriesTrip.getId(), tokenUser.getId(), null, null);
            if (!result.isSuccess()) {
                throw new BusinessException(SystemError.SYS_408);
            }
            seriesTrip.setApprovalId(result.getData().getApprovalId());
            seriesTrip.setStatus(TripStatusConstants.UNDER_APPROVAL.getCode());
//          seriesTrip.setStatus(TripStatusConstants.EFFECTIVE.getCode());
        }
        seriesTrip.setGmtModified(LocalDateTime.now());
        int i = baseMapper.updateById(seriesTrip);
        if (i < 1) {
            throw new BusinessException(SystemError.SYS_408);
        }
        // 更新缓存
        CompletableFuture.runAsync(() -> {
            if (updateStatusReq.getStatus().intValue() != TripStatusConstants.EFFECTIVE.getCode().intValue()) {
                iSeriesTripAppService.deleteTripCache(updateStatusReq.getId());
            } else {
                iSeriesTripAppService.updateTripCache(new TripCacheUpdateReq().setIds(Arrays.asList(seriesTrip.getId())));
            }
        });
    }

    @Override
    public void updateTripScheduleStatus(UpdateTripScheduleStatusReq updateTripScheduleStatusReq) {

        Integer type = updateTripScheduleStatusReq.getType();
        QueryWrapper<SeriesTripSchedule> queryWrapper = new QueryWrapper<SeriesTripSchedule>();
        queryWrapper.lambda().eq(SeriesTripSchedule::getTripId, updateTripScheduleStatusReq.getId());

        //批量开售
        if (type == 1) {
            queryWrapper.lambda().eq(SeriesTripSchedule::getScheduleStatus, TripScheduleStatusConstants.HALT_THE_SALES.getCode());
        }

        //批量禁售
        if (type == 2) {
            queryWrapper.lambda().eq(SeriesTripSchedule::getScheduleStatus, TripScheduleStatusConstants.UNGROUPED.getCode()).or().eq(SeriesTripSchedule::getScheduleStatus, TripScheduleStatusConstants.GROUP.getCode());
        }

        List<SeriesTripSchedule> list = seriesTripScheduleService.list(queryWrapper);
        List<SeriesTripSchedule> tripScheduleList = new ArrayList<>();
        SeriesTripSchedule tripSchedule = null;
        for (SeriesTripSchedule seriesTripSchedule : list) {
            tripSchedule = new SeriesTripSchedule();
            tripSchedule.setId(seriesTripSchedule.getId());
            if (type == 1) {
                tripSchedule.setScheduleStatus(seriesTripSchedule.getLastStatus());
                tripSchedule.setLastStatus(seriesTripSchedule.getScheduleStatus());
            }
            if (type == 2) {
                tripSchedule.setScheduleStatus(TripScheduleStatusConstants.HALT_THE_SALES.getCode());
                tripSchedule.setLastStatus(seriesTripSchedule.getScheduleStatus());
            }
            tripScheduleList.add(tripSchedule);
        }
        seriesTripScheduleService.updateBatchById(tripScheduleList);

        // 更新缓存
        CompletableFuture.runAsync(() -> {
            iSeriesTripAppService.updateTripCache(new TripCacheUpdateReq().setIds(Arrays.asList(updateTripScheduleStatusReq.getId())));
        });
    }

    @Override
    public void addTripFile(AddTripFileReq addTripFileReq, TokenUser tokenUser) {
        List<FileReq> fileReqList = addTripFileReq.getFileList();
        if (CollectionUtils.isNotEmpty(fileReqList)) {
            List<SeriesTripFiles> seriesTripFilesList = new ArrayList<>();
            for (FileReq fileReq : fileReqList) {
                SeriesTripFiles seriesTripFiles = new SeriesTripFiles();
                seriesTripFiles.setFileName(fileReq.getFileName());
                seriesTripFiles.setFileUrl(fileReq.getFileUrl());
                seriesTripFiles.setTripId(addTripFileReq.getTripId());
                seriesTripFiles.setTypeId(addTripFileReq.getTypeId());
                seriesTripFiles.setTypeName(addTripFileReq.getTypeName());
                seriesTripFiles.setCreateId(tokenUser.getId());
                seriesTripFiles.setGmtCreate(LocalDateTime.now());
                seriesTripFiles.setIsDeleted(0);
                seriesTripFilesList.add(seriesTripFiles);
            }
            seriesTripFilesMapper.insertBatchSomeColumn(seriesTripFilesList);
        }
        if (addTripFileReq.getTypeId() == 1) {
            //todo 如果上传文件类型为tic文件。更改tic文件状态
            SeriesTrip seriesTrip = new SeriesTrip();
            seriesTrip.setId(addTripFileReq.getTripId());
            seriesTrip.setTicStatus(2);
            baseMapper.updateById(seriesTrip);
        }
    }

    @Override
    public List<TripFileDTO> tripFileList(Long id) {
        List<SeriesTripFiles> seriesTripFilesList = seriesTripFilesMapper.selectList(new QueryWrapper<SeriesTripFiles>().lambda().eq(SeriesTripFiles::getTripId, id).eq(SeriesTripFiles::getIsDeleted, 0));
        return EntityUtil.copyList(seriesTripFilesList, TripFileDTO.class);
    }

    @Override
    public List<FileReq> recordFileList(Long id) {
        SeriesTrip seriesTrip = seriesTripMapper.selectOne(new QueryWrapper<SeriesTrip>().lambda()
                .eq(SeriesTrip::getId, id)
                .eq(SeriesTrip::getIsDeleted, 0)
                .select(SeriesTrip::getCostSharingType));
        if (seriesTrip == null || seriesTrip.getCostSharingType() == null){
            throw new BusinessException(SystemError.TOUR_30012);
        }
        if(Objects.equals(seriesTrip.getCostSharingType(),1)){
            //默认模板
            List<SeriesTripDefaultCost> list = seriesTripDefaultCostMapper.selectList(new QueryWrapper<SeriesTripDefaultCost>().lambda().eq(SeriesTripDefaultCost::getTripId, id).eq(SeriesTripDefaultCost::getIsDeleted, 0));
            if (CollectionUtils.isNotEmpty(list)){
                SeriesTripDefaultCost seriesTripDefaultCost = list.get(0);
                if (seriesTripDefaultCost != null && CollectionUtils.isNotEmpty(seriesTripDefaultCost.getQuotationFileUrl())){
                    return seriesTripDefaultCost.getQuotationFileUrl();
                }
            }
        }else{
            //自定义模板
            List<SeriesTripCustomCost> list = seriesTripCustomCostMapper.selectList(new QueryWrapper<SeriesTripCustomCost>().lambda().eq(SeriesTripCustomCost::getTripId, id).eq(SeriesTripCustomCost::getIsDeleted,0));
            if (CollectionUtils.isNotEmpty(list)){
                SeriesTripCustomCost seriesTripCustomCost = list.get(0);
                if (seriesTripCustomCost != null && CollectionUtils.isNotEmpty(seriesTripCustomCost.getQuotationFileUrl())){
                    return seriesTripCustomCost.getQuotationFileUrl();
                }
            }
        }
        return null;
    }

    @Override
    public List<SeriesTripTouristTypeDTO> tripTouristType(Long id) {
        List<SeriesTripTouristType> seriesTripTouristTypeList = seriesTripTouristTypeMapper.selectList(new QueryWrapper<SeriesTripTouristType>().lambda().eq(SeriesTripTouristType::getTripId, id).orderByDesc(SeriesTripTouristType::getSort));
        return EntityUtil.copyList(seriesTripTouristTypeList, SeriesTripTouristTypeDTO.class);
    }

    @Override
    public List<SeriesTripDTO> tripScheduleList(TripListQueryReq tripListQueryReq, TokenUser tokenUser) {
        List<Long> permissionList = sysPermissionService.queryPermission(tripListQueryReq.getMenuId(), tokenUser.getId()).ok();
        if (Assist.isEmpty(permissionList)) {
            return Assist.newList();
        }

        QueryWrapper<SeriesTrip> queryWrapper = new QueryWrapper<>();
        String title = tripListQueryReq.getTitle();
        if (StringUtils.isNotBlank(title)) {
            queryWrapper.lambda().and(wrapper -> wrapper.like(SeriesTrip::getTitle, title).or().like(SeriesTrip::getTripCode, title));
        }
        queryWrapper.eq("status", 3);
        queryWrapper.lambda().and(wrapper -> wrapper.in(SeriesTrip::getChargePersonId, permissionList).or().in(SeriesTrip::getOpId, permissionList));
        List<SeriesTrip> seriesTripList = baseMapper.selectList(queryWrapper);
        return EntityUtil.copyList(seriesTripList, SeriesTripDTO.class);
    }

    @Override
    public void approval(TripApprovalReq tripApprovalReq, TokenUser tokenUser) {
        Result<ApprovalCheckDTO> result = sysApprovalService.check(tripApprovalReq.getApprovalId(), tokenUser.getId(), tripApprovalReq.getApprovalType(), tripApprovalReq.getRemarks());
        if (!result.isSuccess()) {
            SystemError error = SystemError.getDefined(result.getCode());
            throw new BusinessException(error);
        }

        if (result.getData().getIsFinish()) {
            SeriesTrip seriesTrip = new SeriesTrip();
            seriesTrip.setId(tripApprovalReq.getTripId());

            //审批通过
            if (ApprovalStatus.REVIEW_YES.getCode().equals(tripApprovalReq.getApprovalType())) {
                seriesTrip.setStatus(TripStatusConstants.EFFECTIVE.getCode());
            } else if (ApprovalStatus.REVIEW_NO.getCode().equals(tripApprovalReq.getApprovalType())) {  //审批通过
                seriesTrip.setStatus(TripStatusConstants.APPROVAL_FAILED.getCode());
            } else if (ApprovalStatus.RECALL.getCode().equals(tripApprovalReq.getApprovalType())) {  //审批不通过
                seriesTrip.setStatus(TripStatusConstants.INVALID.getCode());
            }

            baseMapper.updateById(seriesTrip);
        }

    }

    /**
     * 旅行团行程码是否已存在
     *
     * @param tripCode
     * @return
     */
    @Override
    public Result<Boolean> isExistsTripCode(String tripCode) {
        boolean exists = Assist.isNotEmpty(seriesTripMapper.selectListByKey("trip_code", tripCode));
        return new Result(exists);
    }

    /**
     * 查询行标题
     *
     * @param tripId
     * @return
     */
    @Override
    public String findTripSubject(Long tripId) {
        SeriesTrip seriesTrip = baseMapper.selectById(tripId);
        return seriesTrip.getTitle();
    }

    /**
     * 设置当季热点
     *
     * @param tripId
     * @return
     */
    @Override
    public Result<Void> changeHot(String tripId, Long userId) {
        SeriesTrip entity = seriesTripMapper.assertExistById(tripId);
        fillUpdateEntity(entity);

        if (BConst.ZERO.equals(entity.getIsHot())) {
            entity.setIsHot(BConst.ONE);
        } else {
            entity.setIsHot(BConst.ZERO);
        }

        seriesTripMapper.updateById(entity);

        // 更新缓存
        CompletableFuture.runAsync(() -> {
            iSeriesTripAppService.updateTripCache(new TripCacheUpdateReq().setIds(Arrays.asList(Long.valueOf(tripId))));
        });
        return newResult();
    }

    @Override
    public Integer findTripBusinessTypeById(Long tripId) {
        SeriesTrip seriesTrip = baseMapper.selectOne(Wrappers.<SeriesTrip>lambdaQuery().select(SeriesTrip::getBusinessType)
                .eq(SeriesTrip::getId, tripId)
                .eq(SeriesTrip::getIsDeleted, IsDeletedCode.NO.getCode()));
        if (ObjectUtils.isNotEmpty(seriesTrip)) {
            return seriesTrip.getBusinessType();
        }
        return null;
    }

    @Override
    public Trip queryTripById(Long tripId) {
        SeriesTrip seriesTrip = baseMapper.selectById(tripId);
        return EntityUtil.copy(seriesTrip,Trip.class);
    }
}
